import React, { useEffect, useState } from 'react';
import { message, Row, Col, Form } from 'antd';
import { formatMessage } from 'umi';
import Button from '@/zero/components/Button';
import styles from './index.less';

// Insert one space between two chinese characters automatically.
const fixTwoCNChar = (text) => {
  if (/^[\u4e00-\u9fa5]{2}$/.test(text)) {
    return text.split('').join(' ');
  }
  return text;
};

const Index = (props) => {
  const {
    loading,

    actionsWrapperStyle,

    defaultRowLayout,
    defaultColLayout,
    markModified = true, // 标记已修改（*）
    disabled,

    okText = formatMessage({ id: '保存' }),
    okButtonProps,
    onOk,
    onSubmit = (newValue, success) => {
      console.log('Submit:', newValue);
      success();
    },
    resetText = formatMessage({ id: '重置' }),
    resetButtonProps,
    onReset,

    items = [],
    initialValue = {},

    onValuesChange,
    onDirtyChange,

    skipValidation,

    renderActions = ({ disabled: newDisabled, okButton, resetButton }) =>
      !newDisabled && (
        <>
          {okButton}

          {resetButton}
        </>
      ),

    form: outerForm,

    dispatch,
    ...rest
  } = props;

  const [innerForm] = Form.useForm();

  const form = outerForm || innerForm;

  const [dirty, setDirty] = useState(false);

  const [innerLoading, setInnerLoading] = useState(false);

  useEffect(() => {
    if (onDirtyChange) {
      onDirtyChange(dirty);
    }
  }, [dirty]);

  useEffect(() => {
    form.resetFields();
  }, [JSON.stringify(initialValue)]);

  const execOk = (submitProps = {}, newSkipValidation = skipValidation) => {
    const newPush = (finalRecord) => {
      const push = onOk || onSubmit;
      push(
        finalRecord,

        (content) => {
          if (content !== null) {
            message.success({
              key: 'KEY_FORM',
              content: content || `${formatMessage({ id: '操作成功' })}`,
              duration: 3.5,
            });
          }
          setInnerLoading(false);
          setDirty(false);
          form.submit(); // 用以触发 Form.Provider => onFormFinish
        }, // success

        (content) => {
          if (content !== null) {
            message.error({
              key: 'KEY_FORM',
              content: content || `${formatMessage({ id: '操作失败' })}`,
              duration: 5,
            });
          }
          setInnerLoading(false);
        }, // error

        form,

        {
          ...submitProps,

          dirty,
          setDirty,

          innerLoading,
          setInnerLoading,
        },
      );

      setInnerLoading(true);
    };

    if (newSkipValidation) {
      const finalRecord = form.getFieldsValue();
      newPush(finalRecord);
    } else {
      form
        .validateFields()
        .then((finalRecord) => {
          newPush(finalRecord);
        })
        .catch((errorInfo) => {
          if (errorInfo.errorFields) {
            form.scrollToField(errorInfo.errorFields[0]?.name);
          } else {
            console.log(errorInfo);
          }
        });
    }
  };

  const execReset = () => {
    setDirty(false);
    form.resetFields();
    if (onReset) {
      onReset();
    }
  };

  const newItems = typeof items === 'function' ? items({ disabled }) : items;

  return (
    <>
      <div className={styles.form}>
        <Form
          form={form}
          {...rest}
          onValuesChange={(changedValues, allValues) => {
            setDirty(true);
            if (onValuesChange) {
              onValuesChange(changedValues, allValues);
            }
          }}
          initialValues={initialValue}
        >
          <Row gutter={16} {...defaultRowLayout}>
            {newItems.map((item, index) => (
              <Col key={index} span={24} {...defaultColLayout} {...item.colLayout}>
                {item.field ? (
                  <Form.Item {...item} name={item.name || item.field}>
                    {item.child}
                  </Form.Item>
                ) : (
                  item.child
                )}
              </Col>
            ))}
          </Row>
        </Form>
      </div>

      <div style={{ position: 'relative', ...actionsWrapperStyle }}>
        {renderActions({
          disabled,
          dirty,
          form,

          ok: execOk,
          okButton: (
            <Button
              loading={loading !== undefined ? loading : innerLoading}
              type="primary"
              style={{ minWidth: 75 }}
              {...okButtonProps}
              onClick={() => {
                execOk();
              }}
            >
              {fixTwoCNChar(okText)}
              {markModified && dirty && <span style={{ marginLeft: 5 }}>*</span>}
            </Button>
          ),

          reset: execReset,
          resetButton: (
            <Button
              style={{ minWidth: 75, marginLeft: 15 }}
              {...resetButtonProps}
              onClick={() => {
                execReset();
              }}
            >
              {resetText}
            </Button>
          ),
        })}
      </div>
    </>
  );
};

Object.keys(Form).forEach((item) => {
  if (!['defaultProps'].includes(item)) {
    Index[item] = Form[item];
  }
});

Index.displayName = 'Form';

export default Index;
